package com.example.config;

import com.example.service.SimpleUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// @EnableWebSecurity启用Web安全功能
// 必须加载到rootContext容器中而不是webContext容器
// 因为org.springframework.web.filter.DelegatingFilterProxy#initFilterBean()方法中
// 会（通过org.springframework.web.filter.DelegatingFilterProxy#findWebApplicationContext()方法）
// 查找root application context，然后在org.springframework.web.filter.DelegatingFilterProxy#initDelegate()方法
// 中从root application context中获取名称为"springSecurityFilterChain"的Filter bean（如果正常的话，获取到的
// 应该是FilterChainProxy的实例），如果SecurityConfig没有被加载到root容器中而是被加载到了dispatcherServlet创建的web容器
// 中，那么查找"springSecurityFilterChain"的这一步会抛出“NoSuchBeanDefinitionException:
// No bean named 'springSecurityFilterChain' available”
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /*@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication() // 启用内存用户存储
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user").password(new BCryptPasswordEncoder().encode("123456")).roles("user").and()
                .withUser("admin").password(new BCryptPasswordEncoder().encode("password")).roles("user", "admin");
    }*/


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new SimpleUserDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 指定"/admin"路径的POST请求必须要经过认证
        // anyRequest().permitAll()表明其他的所有请求都是允许的，不需要认证和任何权限
        http.authorizeRequests()
                .antMatchers(HttpMethod.POST,"/admin").authenticated()
                .antMatchers("/admin/**").authenticated()
                .anyRequest().permitAll();
    }
}
